// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Generated by the Codegen C++ plugin.
// If you make any local changes, they will be lost.
// source: google/iam/admin/v1/iam.proto

#ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_IAM_IAM_CLIENT_H
#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_IAM_IAM_CLIENT_H

#include "google/cloud/iam/iam_connection.h"
#include "google/cloud/future.h"
#include "google/cloud/iam_updater.h"
#include "google/cloud/options.h"
#include "google/cloud/polling_policy.h"
#include "google/cloud/status_or.h"
#include "google/cloud/version.h"
#include <memory>

namespace google {
namespace cloud {
namespace iam {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN

///
/// Creates and manages Identity and Access Management (IAM) resources.
///
/// You can use this service to work with all of the following resources:
///
/// * **Service accounts**, which identify an application or a virtual machine
///   (VM) instance rather than a person
/// * **Service account keys**, which service accounts use to authenticate with
///   Google APIs
/// * **IAM policies for service accounts**, which specify the roles that a
///   member has for the service account
/// * **IAM custom roles**, which help you limit the number of permissions that
///   you grant to members
///
/// In addition, you can use this service to complete the following tasks, among
/// others:
///
/// * Test whether a service account can use specific permissions
/// * Check which roles you can grant for a specific resource
/// * Lint, or validate, condition expressions in an IAM policy
///
/// @par Equality
///
/// Instances of this class created via copy-construction or copy-assignment
/// always compare equal. Instances created with equal
/// `std::shared_ptr<*Connection>` objects compare equal. Objects that compare
/// equal share the same underlying resources.
///
/// @par Performance
///
/// Creating a new instance of this class is a relatively expensive operation,
/// new objects establish new connections to the service. In contrast,
/// copy-construction, move-construction, and the corresponding assignment
/// operations are relatively efficient as the copies share all underlying
/// resources.
///
/// @par Thread Safety
///
/// Concurrent access to different instances of this class, even if they compare
/// equal, is guaranteed to work. Two or more threads operating on the same
/// instance of this class is not guaranteed to work. Since copy-construction
/// and move-construction is a relatively efficient operation, consider using
/// such a copy when using this class from multiple threads.
///
class IAMClient {
 public:
  explicit IAMClient(std::shared_ptr<IAMConnection> connection,
                     Options options = {});
  ~IAMClient();

  //@{
  // @name Copy and move support
  IAMClient(IAMClient const&) = default;
  IAMClient& operator=(IAMClient const&) = default;
  IAMClient(IAMClient&&) = default;
  IAMClient& operator=(IAMClient&&) = default;
  //@}

  //@{
  // @name Equality
  friend bool operator==(IAMClient const& a, IAMClient const& b) {
    return a.connection_ == b.connection_;
  }
  friend bool operator!=(IAMClient const& a, IAMClient const& b) {
    return !(a == b);
  }
  //@}

  ///
  /// Lists every [ServiceAccount][google.iam.admin.v1.ServiceAccount] that
  /// belongs to a specific project.
  ///
  /// @param name  Required. The resource name of the project associated with
  /// the service
  ///  accounts, such as `projects/my-project-123`.
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::ServiceAccount,google/iam/admin/v1/iam.proto#L461}
  ///
  /// [google.iam.admin.v1.ListServiceAccountsRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L544}
  /// [google.iam.admin.v1.ServiceAccount]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L461}
  ///
  StreamRange<google::iam::admin::v1::ServiceAccount> ListServiceAccounts(
      std::string const& name, Options options = {});

  ///
  /// Gets a [ServiceAccount][google.iam.admin.v1.ServiceAccount].
  ///
  /// @param name  Required. The resource name of the service account in the
  /// following format:
  ///  `projects/{PROJECT_ID}/serviceAccounts/{ACCOUNT}`.
  ///  Using `-` as a wildcard for the `PROJECT_ID` will infer the project from
  ///  the account. The `ACCOUNT` value can be the `email` address or the
  ///  `unique_id` of the service account.
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::ServiceAccount,google/iam/admin/v1/iam.proto#L461}
  ///
  /// [google.iam.admin.v1.GetServiceAccountRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L579}
  /// [google.iam.admin.v1.ServiceAccount]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L461}
  ///
  StatusOr<google::iam::admin::v1::ServiceAccount> GetServiceAccount(
      std::string const& name, Options options = {});

  ///
  /// Creates a [ServiceAccount][google.iam.admin.v1.ServiceAccount].
  ///
  /// @param name  Required. The resource name of the project associated with
  /// the service
  ///  accounts, such as `projects/my-project-123`.
  /// @param account_id  Required. The account id that is used to generate the
  /// service account
  ///  email address and a stable unique id. It is unique within a project,
  ///  must be 6-30 characters long, and match the regular expression
  ///  `[a-z]([-a-z0-9]*[a-z0-9])` to comply with RFC1035.
  /// @param service_account  The
  /// [ServiceAccount][google.iam.admin.v1.ServiceAccount] resource to
  ///  create. Currently, only the following values are user assignable:
  ///  `display_name` and `description`.
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::ServiceAccount,google/iam/admin/v1/iam.proto#L461}
  ///
  /// [google.iam.admin.v1.CreateServiceAccountRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L521}
  /// [google.iam.admin.v1.ServiceAccount]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L461}
  ///
  StatusOr<google::iam::admin::v1::ServiceAccount> CreateServiceAccount(
      std::string const& name, std::string const& account_id,
      google::iam::admin::v1::ServiceAccount const& service_account,
      Options options = {});

  ///
  /// Deletes a [ServiceAccount][google.iam.admin.v1.ServiceAccount].
  ///
  /// **Warning:** After you delete a service account, you might not be able to
  /// undelete it. If you know that you need to re-enable the service account in
  /// the future, use
  /// [DisableServiceAccount][google.iam.admin.v1.IAM.DisableServiceAccount]
  /// instead.
  ///
  /// If you delete a service account, IAM permanently removes the service
  /// account 30 days later. Google Cloud cannot recover the service account
  /// after it is permanently removed, even if you file a support request.
  ///
  /// To help avoid unplanned outages, we recommend that you disable the service
  /// account before you delete it. Use
  /// [DisableServiceAccount][google.iam.admin.v1.IAM.DisableServiceAccount] to
  /// disable the service account, then wait at least 24 hours and watch for
  /// unintended consequences. If there are no unintended consequences, you can
  /// delete the service account.
  ///
  /// @param name  Required. The resource name of the service account in the
  /// following format:
  ///  `projects/{PROJECT_ID}/serviceAccounts/{ACCOUNT}`.
  ///  Using `-` as a wildcard for the `PROJECT_ID` will infer the project from
  ///  the account. The `ACCOUNT` value can be the `email` address or the
  ///  `unique_id` of the service account.
  /// @param options  Optional. Operation options.
  ///
  /// [google.iam.admin.v1.DeleteServiceAccountRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L594}
  ///
  Status DeleteServiceAccount(std::string const& name, Options options = {});

  ///
  /// Lists every [ServiceAccountKey][google.iam.admin.v1.ServiceAccountKey] for
  /// a service account.
  ///
  /// @param name  Required. The resource name of the service account in the
  /// following format:
  ///  `projects/{PROJECT_ID}/serviceAccounts/{ACCOUNT}`.
  ///  Using `-` as a wildcard for the `PROJECT_ID`, will infer the project from
  ///  the account. The `ACCOUNT` value can be the `email` address or the
  ///  `unique_id` of the service account.
  /// @param key_types  Filters the types of keys the user wants to include in
  /// the list
  ///  response. Duplicate key types are not allowed. If no key type
  ///  is provided, all keys are returned.
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::ListServiceAccountKeysResponse,google/iam/admin/v1/iam.proto#L692}
  ///
  /// [google.iam.admin.v1.ListServiceAccountKeysRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L657}
  /// [google.iam.admin.v1.ListServiceAccountKeysResponse]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L692}
  ///
  StatusOr<google::iam::admin::v1::ListServiceAccountKeysResponse>
  ListServiceAccountKeys(
      std::string const& name,
      std::vector<
          google::iam::admin::v1::ListServiceAccountKeysRequest::KeyType> const&
          key_types,
      Options options = {});

  ///
  /// Gets a [ServiceAccountKey][google.iam.admin.v1.ServiceAccountKey].
  ///
  /// @param name  Required. The resource name of the service account key in the
  /// following format:
  ///  `projects/{PROJECT_ID}/serviceAccounts/{ACCOUNT}/keys/{key}`.
  ///  Using `-` as a wildcard for the `PROJECT_ID` will infer the project from
  ///  the account. The `ACCOUNT` value can be the `email` address or the
  ///  `unique_id` of the service account.
  /// @param public_key_type  The output format of the public key requested.
  ///  X509_PEM is the default output format.
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::ServiceAccountKey,google/iam/admin/v1/iam.proto#L741}
  ///
  /// [google.iam.admin.v1.GetServiceAccountKeyRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L698}
  /// [google.iam.admin.v1.ServiceAccountKey]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L741}
  ///
  StatusOr<google::iam::admin::v1::ServiceAccountKey> GetServiceAccountKey(
      std::string const& name,
      google::iam::admin::v1::ServiceAccountPublicKeyType public_key_type,
      Options options = {});

  ///
  /// Creates a [ServiceAccountKey][google.iam.admin.v1.ServiceAccountKey].
  ///
  /// @param name  Required. The resource name of the service account in the
  /// following format:
  ///  `projects/{PROJECT_ID}/serviceAccounts/{ACCOUNT}`.
  ///  Using `-` as a wildcard for the `PROJECT_ID` will infer the project from
  ///  the account. The `ACCOUNT` value can be the `email` address or the
  ///  `unique_id` of the service account.
  /// @param private_key_type  The output format of the private key. The default
  /// value is
  ///  `TYPE_GOOGLE_CREDENTIALS_FILE`, which is the Google Credentials File
  ///  format.
  /// @param key_algorithm  Which type of key and algorithm to use for the key.
  ///  The default is currently a 2K RSA key.  However this may change in the
  ///  future.
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::ServiceAccountKey,google/iam/admin/v1/iam.proto#L741}
  ///
  /// [google.iam.admin.v1.CreateServiceAccountKeyRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L791}
  /// [google.iam.admin.v1.ServiceAccountKey]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L741}
  ///
  StatusOr<google::iam::admin::v1::ServiceAccountKey> CreateServiceAccountKey(
      std::string const& name,
      google::iam::admin::v1::ServiceAccountPrivateKeyType private_key_type,
      google::iam::admin::v1::ServiceAccountKeyAlgorithm key_algorithm,
      Options options = {});

  ///
  /// Deletes a [ServiceAccountKey][google.iam.admin.v1.ServiceAccountKey].
  /// Deleting a service account key does not revoke short-lived credentials
  /// that have been issued based on the service account key.
  ///
  /// @param name  Required. The resource name of the service account key in the
  /// following format:
  ///  `projects/{PROJECT_ID}/serviceAccounts/{ACCOUNT}/keys/{key}`.
  ///  Using `-` as a wildcard for the `PROJECT_ID` will infer the project from
  ///  the account. The `ACCOUNT` value can be the `email` address or the
  ///  `unique_id` of the service account.
  /// @param options  Optional. Operation options.
  ///
  /// [google.iam.admin.v1.DeleteServiceAccountKeyRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L832}
  ///
  Status DeleteServiceAccountKey(std::string const& name, Options options = {});

  ///
  /// Gets the IAM policy that is attached to a
  /// [ServiceAccount][google.iam.admin.v1.ServiceAccount]. This IAM policy
  /// specifies which members have access to the service account.
  ///
  /// This method does not tell you whether the service account has been granted
  /// any roles on other resources. To check whether a service account has role
  /// grants on a resource, use the `getIamPolicy` method for that resource. For
  /// example, to view the role grants for a project, call the Resource Manager
  /// API's
  /// [`projects.getIamPolicy`](https://cloud.google.com/resource-manager/reference/rest/v1/projects/getIamPolicy)
  /// method.
  ///
  /// @param resource  REQUIRED: The resource for which the policy is being
  /// requested.
  ///  See the operation documentation for the appropriate value for this field.
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::v1::Policy,google/iam/v1/policy.proto#L88}
  ///
  /// [google.iam.v1.GetIamPolicyRequest]:
  /// @googleapis_reference_link{google/iam/v1/iam_policy.proto#L113}
  /// [google.iam.v1.Policy]:
  /// @googleapis_reference_link{google/iam/v1/policy.proto#L88}
  ///
  StatusOr<google::iam::v1::Policy> GetIamPolicy(std::string const& resource,
                                                 Options options = {});

  ///
  /// Sets the IAM policy that is attached to a
  /// [ServiceAccount][google.iam.admin.v1.ServiceAccount].
  ///
  /// Use this method to grant or revoke access to the service account. For
  /// example, you could grant a member the ability to impersonate the service
  /// account.
  ///
  /// This method does not enable the service account to access other resources.
  /// To grant roles to a service account on a resource, follow these steps:
  ///
  /// 1. Call the resource's `getIamPolicy` method to get its current IAM
  /// policy.
  /// 2. Edit the policy so that it binds the service account to an IAM role for
  /// the resource.
  /// 3. Call the resource's `setIamPolicy` method to update its IAM policy.
  ///
  /// For detailed instructions, see
  /// [Granting roles to a service account for specific
  /// resources](https://cloud.google.com/iam/help/service-accounts/granting-access-to-service-accounts).
  ///
  /// @param resource  REQUIRED: The resource for which the policy is being
  /// specified.
  ///  See the operation documentation for the appropriate value for this field.
  /// @param policy  REQUIRED: The complete policy to be applied to the
  /// `resource`. The size of
  ///  the policy is limited to a few 10s of KB. An empty policy is a
  ///  valid policy but certain Cloud Platform services (such as Projects)
  ///  might reject them.
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::v1::Policy,google/iam/v1/policy.proto#L88}
  ///
  /// [google.iam.v1.SetIamPolicyRequest]:
  /// @googleapis_reference_link{google/iam/v1/iam_policy.proto#L98}
  /// [google.iam.v1.Policy]:
  /// @googleapis_reference_link{google/iam/v1/policy.proto#L88}
  ///
  StatusOr<google::iam::v1::Policy> SetIamPolicy(
      std::string const& resource, google::iam::v1::Policy const& policy,
      Options options = {});

  /**
   * Updates the IAM policy for @p resource using an optimistic concurrency
   * control loop.
   *
   * The loop fetches the current policy for @p resource, and passes it to @p
   * updater, which should return the new policy. This new policy should use the
   * current etag so that the read-modify-write cycle can detect races and rerun
   * the update when there is a mismatch. If the new policy does not have an
   * etag, the existing policy will be blindly overwritten. If @p updater does
   * not yield a policy, the control loop is terminated and kCancelled is
   * returned.
   *
   * @param resource  Required. The resource for which the policy is being
   * specified. See the operation documentation for the appropriate value for
   * this field.
   * @param updater  Required. Functor to map the current policy to a new one.
   * @param options  Optional. Options to control the loop. Expected options
   * are:
   *       - `IAMBackoffPolicyOption`
   * @return google::iam::v1::Policy
   */
  StatusOr<google::iam::v1::Policy> SetIamPolicy(std::string const& resource,
                                                 IamUpdater const& updater,
                                                 Options options = {});

  ///
  /// Tests whether the caller has the specified permissions on a
  /// [ServiceAccount][google.iam.admin.v1.ServiceAccount].
  ///
  /// @param resource  REQUIRED: The resource for which the policy detail is
  /// being requested.
  ///  See the operation documentation for the appropriate value for this field.
  /// @param permissions  The set of permissions to check for the `resource`.
  /// Permissions with
  ///  wildcards (such as '*' or 'storage.*') are not allowed. For more
  ///  information see
  ///  [IAM Overview](https://cloud.google.com/iam/docs/overview#permissions).
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::v1::TestIamPermissionsResponse,google/iam/v1/iam_policy.proto#L141}
  ///
  /// [google.iam.v1.TestIamPermissionsRequest]:
  /// @googleapis_reference_link{google/iam/v1/iam_policy.proto#L126}
  /// [google.iam.v1.TestIamPermissionsResponse]:
  /// @googleapis_reference_link{google/iam/v1/iam_policy.proto#L141}
  ///
  StatusOr<google::iam::v1::TestIamPermissionsResponse> TestIamPermissions(
      std::string const& resource, std::vector<std::string> const& permissions,
      Options options = {});

  ///
  /// Lists roles that can be granted on a Google Cloud resource. A role is
  /// grantable if the IAM policy for the resource can contain bindings to the
  /// role.
  ///
  /// @param full_resource_name  Required. The full resource name to query from
  /// the list of grantable roles.
  ///  The name follows the Google Cloud Platform resource format.
  ///  For example, a Cloud Platform project with id `my-project` will be named
  ///  `//cloudresourcemanager.googleapis.com/projects/my-project`.
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::Role,google/iam/admin/v1/iam.proto#L1004}
  ///
  /// [google.iam.admin.v1.QueryGrantableRolesRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L1062}
  /// [google.iam.admin.v1.Role]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L1004}
  ///
  StreamRange<google::iam::admin::v1::Role> QueryGrantableRoles(
      std::string const& full_resource_name, Options options = {});

  ///
  /// Lists every [ServiceAccount][google.iam.admin.v1.ServiceAccount] that
  /// belongs to a specific project.
  ///
  /// @param request
  /// @googleapis_link{google::iam::admin::v1::ListServiceAccountsRequest,google/iam/admin/v1/iam.proto#L544}
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::ServiceAccount,google/iam/admin/v1/iam.proto#L461}
  ///
  /// [google.iam.admin.v1.ListServiceAccountsRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L544}
  /// [google.iam.admin.v1.ServiceAccount]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L461}
  ///
  StreamRange<google::iam::admin::v1::ServiceAccount> ListServiceAccounts(
      google::iam::admin::v1::ListServiceAccountsRequest request,
      Options options = {});

  ///
  /// Gets a [ServiceAccount][google.iam.admin.v1.ServiceAccount].
  ///
  /// @param request
  /// @googleapis_link{google::iam::admin::v1::GetServiceAccountRequest,google/iam/admin/v1/iam.proto#L579}
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::ServiceAccount,google/iam/admin/v1/iam.proto#L461}
  ///
  /// [google.iam.admin.v1.GetServiceAccountRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L579}
  /// [google.iam.admin.v1.ServiceAccount]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L461}
  ///
  StatusOr<google::iam::admin::v1::ServiceAccount> GetServiceAccount(
      google::iam::admin::v1::GetServiceAccountRequest const& request,
      Options options = {});

  ///
  /// Creates a [ServiceAccount][google.iam.admin.v1.ServiceAccount].
  ///
  /// @param request
  /// @googleapis_link{google::iam::admin::v1::CreateServiceAccountRequest,google/iam/admin/v1/iam.proto#L521}
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::ServiceAccount,google/iam/admin/v1/iam.proto#L461}
  ///
  /// [google.iam.admin.v1.CreateServiceAccountRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L521}
  /// [google.iam.admin.v1.ServiceAccount]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L461}
  ///
  StatusOr<google::iam::admin::v1::ServiceAccount> CreateServiceAccount(
      google::iam::admin::v1::CreateServiceAccountRequest const& request,
      Options options = {});

  ///
  /// Patches a [ServiceAccount][google.iam.admin.v1.ServiceAccount].
  ///
  /// @param request
  /// @googleapis_link{google::iam::admin::v1::PatchServiceAccountRequest,google/iam/admin/v1/iam.proto#L616}
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::ServiceAccount,google/iam/admin/v1/iam.proto#L461}
  ///
  /// [google.iam.admin.v1.PatchServiceAccountRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L616}
  /// [google.iam.admin.v1.ServiceAccount]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L461}
  ///
  StatusOr<google::iam::admin::v1::ServiceAccount> PatchServiceAccount(
      google::iam::admin::v1::PatchServiceAccountRequest const& request,
      Options options = {});

  ///
  /// Deletes a [ServiceAccount][google.iam.admin.v1.ServiceAccount].
  ///
  /// **Warning:** After you delete a service account, you might not be able to
  /// undelete it. If you know that you need to re-enable the service account in
  /// the future, use
  /// [DisableServiceAccount][google.iam.admin.v1.IAM.DisableServiceAccount]
  /// instead.
  ///
  /// If you delete a service account, IAM permanently removes the service
  /// account 30 days later. Google Cloud cannot recover the service account
  /// after it is permanently removed, even if you file a support request.
  ///
  /// To help avoid unplanned outages, we recommend that you disable the service
  /// account before you delete it. Use
  /// [DisableServiceAccount][google.iam.admin.v1.IAM.DisableServiceAccount] to
  /// disable the service account, then wait at least 24 hours and watch for
  /// unintended consequences. If there are no unintended consequences, you can
  /// delete the service account.
  ///
  /// @param request
  /// @googleapis_link{google::iam::admin::v1::DeleteServiceAccountRequest,google/iam/admin/v1/iam.proto#L594}
  /// @param options  Optional. Operation options.
  ///
  /// [google.iam.admin.v1.DeleteServiceAccountRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L594}
  ///
  Status DeleteServiceAccount(
      google::iam::admin::v1::DeleteServiceAccountRequest const& request,
      Options options = {});

  ///
  /// Restores a deleted [ServiceAccount][google.iam.admin.v1.ServiceAccount].
  ///
  /// **Important:** It is not always possible to restore a deleted service
  /// account. Use this method only as a last resort.
  ///
  /// After you delete a service account, IAM permanently removes the service
  /// account 30 days later. There is no way to restore a deleted service
  /// account that has been permanently removed.
  ///
  /// @param request
  /// @googleapis_link{google::iam::admin::v1::UndeleteServiceAccountRequest,google/iam/admin/v1/iam.proto#L623}
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::UndeleteServiceAccountResponse,google/iam/admin/v1/iam.proto#L631}
  ///
  /// [google.iam.admin.v1.UndeleteServiceAccountRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L623}
  /// [google.iam.admin.v1.UndeleteServiceAccountResponse]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L631}
  ///
  StatusOr<google::iam::admin::v1::UndeleteServiceAccountResponse>
  UndeleteServiceAccount(
      google::iam::admin::v1::UndeleteServiceAccountRequest const& request,
      Options options = {});

  ///
  /// Enables a [ServiceAccount][google.iam.admin.v1.ServiceAccount] that was
  /// disabled by
  /// [DisableServiceAccount][google.iam.admin.v1.IAM.DisableServiceAccount].
  ///
  /// If the service account is already enabled, then this method has no effect.
  ///
  /// If the service account was disabled by other means—for example, if Google
  /// disabled the service account because it was compromised—you cannot use
  /// this method to enable the service account.
  ///
  /// @param request
  /// @googleapis_link{google::iam::admin::v1::EnableServiceAccountRequest,google/iam/admin/v1/iam.proto#L637}
  /// @param options  Optional. Operation options.
  ///
  /// [google.iam.admin.v1.EnableServiceAccountRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L637}
  ///
  Status EnableServiceAccount(
      google::iam::admin::v1::EnableServiceAccountRequest const& request,
      Options options = {});

  ///
  /// Disables a [ServiceAccount][google.iam.admin.v1.ServiceAccount]
  /// immediately.
  ///
  /// If an application uses the service account to authenticate, that
  /// application can no longer call Google APIs or access Google Cloud
  /// resources. Existing access tokens for the service account are rejected,
  /// and requests for new access tokens will fail.
  ///
  /// To re-enable the service account, use
  /// [EnableServiceAccount][google.iam.admin.v1.IAM.EnableServiceAccount].
  /// After you re-enable the service account, its existing access tokens will
  /// be accepted, and you can request new access tokens.
  ///
  /// To help avoid unplanned outages, we recommend that you disable the service
  /// account before you delete it. Use this method to disable the service
  /// account, then wait at least 24 hours and watch for unintended
  /// consequences. If there are no unintended consequences, you can delete the
  /// service account with
  /// [DeleteServiceAccount][google.iam.admin.v1.IAM.DeleteServiceAccount].
  ///
  /// @param request
  /// @googleapis_link{google::iam::admin::v1::DisableServiceAccountRequest,google/iam/admin/v1/iam.proto#L647}
  /// @param options  Optional. Operation options.
  ///
  /// [google.iam.admin.v1.DisableServiceAccountRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L647}
  ///
  Status DisableServiceAccount(
      google::iam::admin::v1::DisableServiceAccountRequest const& request,
      Options options = {});

  ///
  /// Lists every [ServiceAccountKey][google.iam.admin.v1.ServiceAccountKey] for
  /// a service account.
  ///
  /// @param request
  /// @googleapis_link{google::iam::admin::v1::ListServiceAccountKeysRequest,google/iam/admin/v1/iam.proto#L657}
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::ListServiceAccountKeysResponse,google/iam/admin/v1/iam.proto#L692}
  ///
  /// [google.iam.admin.v1.ListServiceAccountKeysRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L657}
  /// [google.iam.admin.v1.ListServiceAccountKeysResponse]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L692}
  ///
  StatusOr<google::iam::admin::v1::ListServiceAccountKeysResponse>
  ListServiceAccountKeys(
      google::iam::admin::v1::ListServiceAccountKeysRequest const& request,
      Options options = {});

  ///
  /// Gets a [ServiceAccountKey][google.iam.admin.v1.ServiceAccountKey].
  ///
  /// @param request
  /// @googleapis_link{google::iam::admin::v1::GetServiceAccountKeyRequest,google/iam/admin/v1/iam.proto#L698}
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::ServiceAccountKey,google/iam/admin/v1/iam.proto#L741}
  ///
  /// [google.iam.admin.v1.GetServiceAccountKeyRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L698}
  /// [google.iam.admin.v1.ServiceAccountKey]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L741}
  ///
  StatusOr<google::iam::admin::v1::ServiceAccountKey> GetServiceAccountKey(
      google::iam::admin::v1::GetServiceAccountKeyRequest const& request,
      Options options = {});

  ///
  /// Creates a [ServiceAccountKey][google.iam.admin.v1.ServiceAccountKey].
  ///
  /// @param request
  /// @googleapis_link{google::iam::admin::v1::CreateServiceAccountKeyRequest,google/iam/admin/v1/iam.proto#L791}
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::ServiceAccountKey,google/iam/admin/v1/iam.proto#L741}
  ///
  /// [google.iam.admin.v1.CreateServiceAccountKeyRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L791}
  /// [google.iam.admin.v1.ServiceAccountKey]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L741}
  ///
  StatusOr<google::iam::admin::v1::ServiceAccountKey> CreateServiceAccountKey(
      google::iam::admin::v1::CreateServiceAccountKeyRequest const& request,
      Options options = {});

  ///
  /// Creates a [ServiceAccountKey][google.iam.admin.v1.ServiceAccountKey],
  /// using a public key that you provide.
  ///
  /// @param request
  /// @googleapis_link{google::iam::admin::v1::UploadServiceAccountKeyRequest,google/iam/admin/v1/iam.proto#L816}
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::ServiceAccountKey,google/iam/admin/v1/iam.proto#L741}
  ///
  /// [google.iam.admin.v1.UploadServiceAccountKeyRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L816}
  /// [google.iam.admin.v1.ServiceAccountKey]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L741}
  ///
  StatusOr<google::iam::admin::v1::ServiceAccountKey> UploadServiceAccountKey(
      google::iam::admin::v1::UploadServiceAccountKeyRequest const& request,
      Options options = {});

  ///
  /// Deletes a [ServiceAccountKey][google.iam.admin.v1.ServiceAccountKey].
  /// Deleting a service account key does not revoke short-lived credentials
  /// that have been issued based on the service account key.
  ///
  /// @param request
  /// @googleapis_link{google::iam::admin::v1::DeleteServiceAccountKeyRequest,google/iam/admin/v1/iam.proto#L832}
  /// @param options  Optional. Operation options.
  ///
  /// [google.iam.admin.v1.DeleteServiceAccountKeyRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L832}
  ///
  Status DeleteServiceAccountKey(
      google::iam::admin::v1::DeleteServiceAccountKeyRequest const& request,
      Options options = {});

  ///
  /// Gets the IAM policy that is attached to a
  /// [ServiceAccount][google.iam.admin.v1.ServiceAccount]. This IAM policy
  /// specifies which members have access to the service account.
  ///
  /// This method does not tell you whether the service account has been granted
  /// any roles on other resources. To check whether a service account has role
  /// grants on a resource, use the `getIamPolicy` method for that resource. For
  /// example, to view the role grants for a project, call the Resource Manager
  /// API's
  /// [`projects.getIamPolicy`](https://cloud.google.com/resource-manager/reference/rest/v1/projects/getIamPolicy)
  /// method.
  ///
  /// @param request
  /// @googleapis_link{google::iam::v1::GetIamPolicyRequest,google/iam/v1/iam_policy.proto#L113}
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::v1::Policy,google/iam/v1/policy.proto#L88}
  ///
  /// [google.iam.v1.GetIamPolicyRequest]:
  /// @googleapis_reference_link{google/iam/v1/iam_policy.proto#L113}
  /// [google.iam.v1.Policy]:
  /// @googleapis_reference_link{google/iam/v1/policy.proto#L88}
  ///
  StatusOr<google::iam::v1::Policy> GetIamPolicy(
      google::iam::v1::GetIamPolicyRequest const& request,
      Options options = {});

  ///
  /// Sets the IAM policy that is attached to a
  /// [ServiceAccount][google.iam.admin.v1.ServiceAccount].
  ///
  /// Use this method to grant or revoke access to the service account. For
  /// example, you could grant a member the ability to impersonate the service
  /// account.
  ///
  /// This method does not enable the service account to access other resources.
  /// To grant roles to a service account on a resource, follow these steps:
  ///
  /// 1. Call the resource's `getIamPolicy` method to get its current IAM
  /// policy.
  /// 2. Edit the policy so that it binds the service account to an IAM role for
  /// the resource.
  /// 3. Call the resource's `setIamPolicy` method to update its IAM policy.
  ///
  /// For detailed instructions, see
  /// [Granting roles to a service account for specific
  /// resources](https://cloud.google.com/iam/help/service-accounts/granting-access-to-service-accounts).
  ///
  /// @param request
  /// @googleapis_link{google::iam::v1::SetIamPolicyRequest,google/iam/v1/iam_policy.proto#L98}
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::v1::Policy,google/iam/v1/policy.proto#L88}
  ///
  /// [google.iam.v1.SetIamPolicyRequest]:
  /// @googleapis_reference_link{google/iam/v1/iam_policy.proto#L98}
  /// [google.iam.v1.Policy]:
  /// @googleapis_reference_link{google/iam/v1/policy.proto#L88}
  ///
  StatusOr<google::iam::v1::Policy> SetIamPolicy(
      google::iam::v1::SetIamPolicyRequest const& request,
      Options options = {});

  ///
  /// Tests whether the caller has the specified permissions on a
  /// [ServiceAccount][google.iam.admin.v1.ServiceAccount].
  ///
  /// @param request
  /// @googleapis_link{google::iam::v1::TestIamPermissionsRequest,google/iam/v1/iam_policy.proto#L126}
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::v1::TestIamPermissionsResponse,google/iam/v1/iam_policy.proto#L141}
  ///
  /// [google.iam.v1.TestIamPermissionsRequest]:
  /// @googleapis_reference_link{google/iam/v1/iam_policy.proto#L126}
  /// [google.iam.v1.TestIamPermissionsResponse]:
  /// @googleapis_reference_link{google/iam/v1/iam_policy.proto#L141}
  ///
  StatusOr<google::iam::v1::TestIamPermissionsResponse> TestIamPermissions(
      google::iam::v1::TestIamPermissionsRequest const& request,
      Options options = {});

  ///
  /// Lists roles that can be granted on a Google Cloud resource. A role is
  /// grantable if the IAM policy for the resource can contain bindings to the
  /// role.
  ///
  /// @param request
  /// @googleapis_link{google::iam::admin::v1::QueryGrantableRolesRequest,google/iam/admin/v1/iam.proto#L1062}
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::Role,google/iam/admin/v1/iam.proto#L1004}
  ///
  /// [google.iam.admin.v1.QueryGrantableRolesRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L1062}
  /// [google.iam.admin.v1.Role]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L1004}
  ///
  StreamRange<google::iam::admin::v1::Role> QueryGrantableRoles(
      google::iam::admin::v1::QueryGrantableRolesRequest request,
      Options options = {});

  ///
  /// Lists every predefined [Role][google.iam.admin.v1.Role] that IAM supports,
  /// or every custom role that is defined for an organization or project.
  ///
  /// @param request
  /// @googleapis_link{google::iam::admin::v1::ListRolesRequest,google/iam/admin/v1/iam.proto#L1093}
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::Role,google/iam/admin/v1/iam.proto#L1004}
  ///
  /// [google.iam.admin.v1.ListRolesRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L1093}
  /// [google.iam.admin.v1.Role]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L1004}
  ///
  StreamRange<google::iam::admin::v1::Role> ListRoles(
      google::iam::admin::v1::ListRolesRequest request, Options options = {});

  ///
  /// Gets the definition of a [Role][google.iam.admin.v1.Role].
  ///
  /// @param request
  /// @googleapis_link{google::iam::admin::v1::GetRoleRequest,google/iam/admin/v1/iam.proto#L1152}
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::Role,google/iam/admin/v1/iam.proto#L1004}
  ///
  /// [google.iam.admin.v1.GetRoleRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L1152}
  /// [google.iam.admin.v1.Role]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L1004}
  ///
  StatusOr<google::iam::admin::v1::Role> GetRole(
      google::iam::admin::v1::GetRoleRequest const& request,
      Options options = {});

  ///
  /// Creates a new custom [Role][google.iam.admin.v1.Role].
  ///
  /// @param request
  /// @googleapis_link{google::iam::admin::v1::CreateRoleRequest,google/iam/admin/v1/iam.proto#L1184}
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::Role,google/iam/admin/v1/iam.proto#L1004}
  ///
  /// [google.iam.admin.v1.CreateRoleRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L1184}
  /// [google.iam.admin.v1.Role]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L1004}
  ///
  StatusOr<google::iam::admin::v1::Role> CreateRole(
      google::iam::admin::v1::CreateRoleRequest const& request,
      Options options = {});

  ///
  /// Updates the definition of a custom [Role][google.iam.admin.v1.Role].
  ///
  /// @param request
  /// @googleapis_link{google::iam::admin::v1::UpdateRoleRequest,google/iam/admin/v1/iam.proto#L1219}
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::Role,google/iam/admin/v1/iam.proto#L1004}
  ///
  /// [google.iam.admin.v1.UpdateRoleRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L1219}
  /// [google.iam.admin.v1.Role]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L1004}
  ///
  StatusOr<google::iam::admin::v1::Role> UpdateRole(
      google::iam::admin::v1::UpdateRoleRequest const& request,
      Options options = {});

  ///
  /// Deletes a custom [Role][google.iam.admin.v1.Role].
  ///
  /// When you delete a custom role, the following changes occur immediately:
  ///
  /// * You cannot bind a member to the custom role in an IAM
  /// [Policy][google.iam.v1.Policy].
  /// * Existing bindings to the custom role are not changed, but they have no
  /// effect.
  /// * By default, the response from
  /// [ListRoles][google.iam.admin.v1.IAM.ListRoles] does not include the custom
  /// role.
  ///
  /// You have 7 days to undelete the custom role. After 7 days, the following
  /// changes occur:
  ///
  /// * The custom role is permanently deleted and cannot be recovered.
  /// * If an IAM policy contains a binding to the custom role, the binding is
  /// permanently removed.
  ///
  /// @param request
  /// @googleapis_link{google::iam::admin::v1::DeleteRoleRequest,google/iam/admin/v1/iam.proto#L1250}
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::Role,google/iam/admin/v1/iam.proto#L1004}
  ///
  /// [google.iam.admin.v1.DeleteRoleRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L1250}
  /// [google.iam.admin.v1.Role]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L1004}
  ///
  StatusOr<google::iam::admin::v1::Role> DeleteRole(
      google::iam::admin::v1::DeleteRoleRequest const& request,
      Options options = {});

  ///
  /// Undeletes a custom [Role][google.iam.admin.v1.Role].
  ///
  /// @param request
  /// @googleapis_link{google::iam::admin::v1::UndeleteRoleRequest,google/iam/admin/v1/iam.proto#L1278}
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::Role,google/iam/admin/v1/iam.proto#L1004}
  ///
  /// [google.iam.admin.v1.UndeleteRoleRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L1278}
  /// [google.iam.admin.v1.Role]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L1004}
  ///
  StatusOr<google::iam::admin::v1::Role> UndeleteRole(
      google::iam::admin::v1::UndeleteRoleRequest const& request,
      Options options = {});

  ///
  /// Lists every permission that you can test on a resource. A permission is
  /// testable if you can check whether a member has that permission on the
  /// resource.
  ///
  /// @param request
  /// @googleapis_link{google::iam::admin::v1::QueryTestablePermissionsRequest,google/iam/admin/v1/iam.proto#L1361}
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::Permission,google/iam/admin/v1/iam.proto#L1306}
  ///
  /// [google.iam.admin.v1.QueryTestablePermissionsRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L1361}
  /// [google.iam.admin.v1.Permission]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L1306}
  ///
  StreamRange<google::iam::admin::v1::Permission> QueryTestablePermissions(
      google::iam::admin::v1::QueryTestablePermissionsRequest request,
      Options options = {});

  ///
  /// Returns a list of services that allow you to opt into audit logs that are
  /// not generated by default.
  ///
  /// To learn more about audit logs, see the [Logging
  /// documentation](https://cloud.google.com/logging/docs/audit).
  ///
  /// @param request
  /// @googleapis_link{google::iam::admin::v1::QueryAuditableServicesRequest,google/iam/admin/v1/iam.proto#L1391}
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::QueryAuditableServicesResponse,google/iam/admin/v1/iam.proto#L1402}
  ///
  /// [google.iam.admin.v1.QueryAuditableServicesRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L1391}
  /// [google.iam.admin.v1.QueryAuditableServicesResponse]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L1402}
  ///
  StatusOr<google::iam::admin::v1::QueryAuditableServicesResponse>
  QueryAuditableServices(
      google::iam::admin::v1::QueryAuditableServicesRequest const& request,
      Options options = {});

  ///
  /// Lints, or validates, an IAM policy. Currently checks the
  /// [google.iam.v1.Binding.condition][google.iam.v1.Binding.condition] field,
  /// which contains a condition expression for a role binding.
  ///
  /// Successful calls to this method always return an HTTP `200 OK` status
  /// code, even if the linter detects an issue in the IAM policy.
  ///
  /// @param request
  /// @googleapis_link{google::iam::admin::v1::LintPolicyRequest,google/iam/admin/v1/iam.proto#L1415}
  /// @param options  Optional. Operation options.
  /// @return
  /// @googleapis_link{google::iam::admin::v1::LintPolicyResponse,google/iam/admin/v1/iam.proto#L1513}
  ///
  /// [google.iam.admin.v1.LintPolicyRequest]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L1415}
  /// [google.iam.admin.v1.LintPolicyResponse]:
  /// @googleapis_reference_link{google/iam/admin/v1/iam.proto#L1513}
  ///
  StatusOr<google::iam::admin::v1::LintPolicyResponse> LintPolicy(
      google::iam::admin::v1::LintPolicyRequest const& request,
      Options options = {});

 private:
  std::shared_ptr<IAMConnection> connection_;
  Options options_;
};

GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
namespace gcpcxxV1 = GOOGLE_CLOUD_CPP_NS;  // NOLINT(misc-unused-alias-decls)
}  // namespace iam
}  // namespace cloud
}  // namespace google

#endif  // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_IAM_IAM_CLIENT_H
